<template>
    <div class="table-box">
        <!-- 搜索框部分 -->
        <search-form ref="searchRef" :searchColumns="props.searchColumns" v-show="isShowSearch"
            @search-change="handleSearch" />
        <!-- 表格部分 -->
        <div class="table-box-content">
            <div class="table-box-content-top" v-if="showToolbar">
                <div class="btn-grop">
                    <slot name="topLeft">
                        <div style="font-size: 16px;font-weight: bold;" v-if="isShowTableTitle">{{ tableTitle }}</div>
                    </slot>
                </div>
                <div style="display: flex;">
                    <slot name="topRight"></slot>
                    <el-tooltip effect="dark" content="刷新当前页" placement="top">
                        <el-button :icon="Refresh" @click="handleRefresh" plain style="margin-left: 10px;"
                            v-if="showRefresh && columnData.length > 0" />
                    </el-tooltip>

                    <el-tooltip effect="dark" content="列设置" placement="top">
                        <el-button :icon="Setting" @click="drawerChange" style="margin-left: 10px;"
                            v-if="showSetting && props.tableKey && props.tableColumns.length > 0" />
                    </el-tooltip>
                    <el-tooltip effect="dark" content="搜索开启/搜索关闭" placement="top">
                        <el-button :icon="!isShowSearch ? View : Hide" @click="changeSearch" plain
                            style="margin-left: 10px;" v-if="showSearch && props.searchColumns.length > 0" />
                    </el-tooltip>

                    <el-tooltip effect="dark" content="全屏/取消全屏" placement="top">
                        <el-button :icon="!isFull ? FullScreen : Rank" @click="handleFullScreen" plain
                            style="margin-left: 10px;" v-if="showFullScreen" />
                    </el-tooltip>
                </div>
            </div>
            <el-table :data="props.tableData.length > 0 ? props.tableData : dataList" :border="border" height="100%"
                row-key="id" ref="multipleTableRef" :stripe="props.stripe" :highlightCurrentRow="isHighlightCurrentRow"
                :row-key="props.rowKey" @row-click="rowClickChange" v-loading="!props.api ? props.showLoading : loading"
                @selection-change="handleSelectionChange" @current-change="handleRadioChange">
                <el-table-column type="selection" align="center" v-if="!isHighlightCurrentRow && isMultiple"
                    width="80"></el-table-column>
                <el-table-column type="index" label="序号" width="80" align="center"
                    v-if="!isMultiple && showIndex"></el-table-column>
                <template v-for="(item, index) in columnData" :key="item.prop">
                    <el-table-column :prop="item.prop" :label="item.title" :align="item.align" :width="item.width"
                        :minWidth="item.minWidth || 120" :fixed="item.fixed" v-if="item.showColumn"
                        :sortable="item.sortable" show-overflow-tooltip>
                        <template v-slot:default="scope">
                            <!-- 传递当前行的值和索引给具名插槽 -->
                            <slot :name="item.prop" :row="scope.row" :index="scope.$index"> {{ scope.row[item.prop] }}
                            </slot>
                        </template>
                    </el-table-column>
                </template>
                <!-- 操作 /更多 -->
                <el-table-column :fixed="props.moreOperations.fixed" :label="props.moreOperations.title"
                    v-if="props.showOperations" :width="props.moreOperations.width" :align="props.moreOperations.align">
                    <template v-slot:default="scope">
                        <slot name="moreColumn" :row="scope.row" :index="scope.$index"></slot>
                    </template>
                </el-table-column>
            </el-table>
            <!-- 底部 -->
            <slot name="footer" />
        </div>
        <drawer-popup :drawer="isDrawer" @close="isDrawer = false" :tableData="JSON.stringify(columnData)"
            @confirm="drawerConfirm" />
    </div>
</template>
<script  setup>
import { ElMessage } from 'element-plus'
import drawerPopup from "@/components/zt-small-tools/drawer-popup.vue"
import searchForm from "@/components/zt-small-tools/search-form.vue"
import { Setting, Refresh, FullScreen, Rank, Hide, View } from '@element-plus/icons-vue'
import useScreenFull from '@/hooks/useScreenFull.js';//引入方法
import { reactive } from 'vue';
import router from "@/router/index";
const { isFull, fullScreen } = useScreenFull();// 全屏

const isDrawer = ref(false) //控制列抽屉弹窗
const formData = ref({}) // 表单数据对象
const multipleTableRef = ref()
const isShowSearch = ref(true)
// 事件
const emit = defineEmits(['row-click', 'multiple-choice', 'radio-change', 'get-data', 'size-change', 'current-change', 'page-change', 'search-change', 'reset', 'refresh',])
const props = defineProps({
    // 表格的唯一key值（不能与localStorage里面存储的值一样，否则会造成数据冲突，取值错误）  如果开启了表格设置功能 需要必传   默认使用路由name
    tableKey: {
        type: String,
        required: true,
        default: () => {
            return router.currentRoute.value.name
        }
    },
    // 接口
    api: {
        type: Function,
    },
    // 自定义的form表单  有的字段需要默认传递 就用此配置
    paramForm: {
        type: Object,
        default: () => { }
    },

    // 传递进来的数据列表 
    tableData: {
        type: Array,
        default: () => []
    },
    // 表格列
    tableColumns: {
        type: Array,
        default: () => []
    },
    // 搜索表单列表
    searchColumns: {
        type: Object,
        default: () => []
    },
    // row-key
    rowKey: {
        type: String,
        default: ''
    },

    // 表格是否带边框
    border: {
        type: Boolean,
        default: true
    },


    // 是否显示下标
    showIndex: {
        type: Boolean,
        default: true
    },
    // 是否多选 默认关闭 跟行单选只能一个为true
    isMultiple: {
        type: Boolean,
        default: false
    },
    // 是否开启点击行选中数据  开启后 触发 rowClickChange 方法
    isClickRow: {
        type: Boolean,
        default: false
    },

    // 是否开启操作列
    showOperations: {
        type: Boolean,
        default: true
    },

    // 更多操作列
    moreOperations: {
        type: Object,
        default: () => {
            return {
                title: '操作', //标题
                align: 'center',//居中方式
                width: '120px',//宽度
                fixed: 'right',//固定定位方向
            }
        }
    },
    // 表格标题名称
    tableTitle: {
        type: String,
        default: () => {
            const route = useRoute();// 获取当前路由信息
            return route.meta.title
        }
    },
    // 是否显示表格标题
    isShowTableTitle: {
        type: Boolean,
        default: true
    },

    // 是否为斑马纹 table
    stripe: {
        type: Boolean,
        default: true
    },

    //行点击 单选
    isHighlightCurrentRow: {
        type: Boolean,
        default: false
    },

    // 是否显示表格上面的工具栏 不要轻易传递false 否则会导致一整排过去都无法显示
    showToolbar: {
        type: Boolean,
        default: true
    },

    // 是否显示刷新图标按钮
    showRefresh: {
        type: Boolean,
        default: true
    },
    // 是否显示设置图标按钮
    showSetting: {
        type: Boolean,
        default: true
    },
    // 是否显示搜索显示/关闭按钮
    showSearch: {
        type: Boolean,
        default: true
    },
    // 是否显示全屏图标按钮
    showFullScreen: {
        type: Boolean,
        default: true
    },
    // 显示刷新按钮
    showRefresh: {
        type: Boolean,
        default: true
    },
    // 表格开启显示加载
    showLoading: {
        type: Boolean,
        default: false
    },

    // 是否开启表格加载
    isTableLoading: {
        type: Boolean,
        default: true
    },
})


const styleObj = ref({})//底部按钮对齐样式
// 设置底部分页对齐方向
watch(() => props.pageSizeAlign, (val) => {
    switch (val) {
        case 'left': // 左对齐
            styleObj.value = {
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'flex-start'
            }
            break;
        case 'right':// 右对齐
            styleObj.value = {
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'flex-end'
            }
            break;
        case 'center'://居中对齐
            styleObj.value = {
                display: 'flex',
                alignItems: 'center',
                justifyContent: 'center'
            }
            break;
    }
}, {
    deep: true,
    immediate: true
})
const columnData = ref([])
// 监听列改变
watch(() => props.tableColumns, (val) => {
    // 判断是否存储
    if (localStorage.getItem(props.tableKey)) {
        let data = JSON.parse(localStorage.getItem(props.tableKey))
        let list = []
        // 拿到之前存储的数据 赋值状态显示
        data.forEach(item => {
            props.tableColumns.forEach(ele => {
                if (item.prop == ele.prop) {
                    ele.showColumn = item.showColumn

                    // // 判断是否有宽度 有宽度就赋值
                    // if (item.width) {
                    //     ele.width = item.width
                    // }

                    list.push(ele)
                }
            })
        });
        // 补全数据 遍历之前list中没有的列
        props.tableColumns.forEach(item => {
            if (!list.find(ele => ele.prop == item.prop)) {
                list.push(item)
            }
        })
        columnData.value = list
    } else {
        columnData.value = toRaw(val)
    }
}, {
    deep: true,
    immediate: true
})

const multipleSelection = ref([])

// 行点击事件
async function rowClickChange(row) {
    // 开启行点击选中时生效
    if (props.isClickRow) {
        multipleTableRef.value.toggleRowSelection(row)
    }
    emit('row-click', row)
}

// 选中事件
async function handleSelectionChange(val) {
    multipleSelection.value = val
    // 多选 选中后的数据导出
    emit('multiple-choice', val)
    // console.log(multipleSelection.value)
}

// 清空选中的数据
async function clearSelection() {
    multipleTableRef.value.clearSelection()
}

// 列选项选中确认事件
async function drawerConfirm(val) {
    columnData.value = JSON.parse(val)
    localStorage.setItem(props.tableKey, JSON.stringify(toRaw(columnData.value)))
    message.success('设置成功')
}

// 搜索表单查询按钮
async function handleSearch(e) {
    // 判断是否传入接口
    if (props.api) {
        formData.value = e
        getApiData()
    } else {
        formData.value = e
        emit('search-change', formData.value)
    }

}
// 重置按钮
async function handleReset(e) {
    formData.value = e
}
// 设置按钮
async function drawerChange() {
    isDrawer.value = true
}

// 刷新按钮
async function handleRefresh() {
    // 判断是否传入接口
    if (props.api) {
        getApiData()
    } else {
        emit('refresh')
    }
}
// 是否显示搜索
async function changeSearch() {
    isShowSearch.value = !isShowSearch.value
}

// 单选模式 数据选中事件
async function handleRadioChange(e) {
    emit('radio-change', toRaw(e))
}

//全屏功能
async function handleFullScreen() {
    fullScreen()
}

const dataList = ref([])
// 加载状态
const loading = ref(false)
// 请求数据
function getApiData() {
    // 判断是否传入接口 没有传入则不执行
    if (!props.api) return

    // 判断传入的接口是不是一个字符串 
    if (typeof (props.api) == 'string') return ElMessage.warning('请传递正确的接口')
    // 判断是否开启了表格加载
    if (props.isTableLoading) {
        loading.value = true
    }
    props.api({
        ...formData.value,
        ...props.paramForm
    },).then(res => {
        dataList.value = res.data || []
        emit('get-data', res)
    }).finally(() => {
        loading.value = false
    })
}

// 重新加载
function reload() {
    getApiData()
}

getApiData()

// 导出方法  开启了setup 方法需要导出
defineExpose({
    reload
});


</script>

<style lang='scss' scoped>
.table-box {
    display: flex;
    flex-direction: column;
    height: 100%;
    width: 100%;



    .table-box-content {
        flex: 1;
        overflow-y: scroll;
        display: flex;
        flex-direction: column;
        margin-top: 10px;
        box-shadow: 0 0 5px 5px #f7f7f7;
        padding: 16px;
        box-sizing: border-box;
        border-radius: 5px;


        .table-box-content-top {
            display: flex;
            align-items: center;
            justify-content: space-between;
            margin-bottom: 16px;
        }
    }

    .table-box-content::-webkit-scrollbar {
        width: 0px !important;
        height: 0px;
    }

    .table-box-footer {
        padding: 0 10px;
        box-sizing: border-box;
        margin-top: 1rem;
    }
}
</style>
<style lang="scss">
.table-box {
    .table-box-search {
        .el-form {
            .el-form-item__content {
                .el-input__wrapper {
                    width: 100%;
                }
            }
        }
    }
}
</style>
